From c65d6353512ae6f1671723502b710c290a6be745 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Thu, 17 Nov 2005 12:52:42 +0100 Subject: [PATCH] The perdomain mapping area in Xen space requires more than one level-1 pagetable page on PAE and x86/64. Generalise the existing code to allocate and map an appropriate number of level-1 pagetable pages. Signed-off-by: Jun Nakajima Signed-off-by: Keir Fraser --- xen/arch/x86/domain.c | 24 +++++++++++++----------- xen/arch/x86/mm.c | 2 +- xen/arch/x86/shadow.c | 2 +- xen/include/asm-x86/config.h | 3 +++ 4 files changed, 18 insertions(+), 13 deletions(-) diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index c6a334f8d1..6f48b62bdc 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -240,7 +240,10 @@ void free_vcpu_struct(struct vcpu *v) void free_perdomain_pt(struct domain *d) { - free_xenheap_page(d->arch.mm_perdomain_pt); + free_xenheap_pages( + d->arch.mm_perdomain_pt, + get_order_from_bytes(PDPT_L1_ENTRIES * sizeof(l1_pgentry_t))); + #ifdef __x86_64__ free_xenheap_page(d->arch.mm_perdomain_l2); free_xenheap_page(d->arch.mm_perdomain_l3); @@ -251,7 +254,7 @@ void arch_do_createdomain(struct vcpu *v) { struct domain *d = v->domain; l1_pgentry_t gdt_l1e; - int vcpuid; + int vcpuid, pdpt_order; if ( is_idle_task(d) ) return; @@ -263,13 +266,10 @@ void arch_do_createdomain(struct vcpu *v) v->vcpu_info = &d->shared_info->vcpu_data[v->vcpu_id]; v->cpumap = CPUMAP_RUNANYWHERE; SHARE_PFN_WITH_DOMAIN(virt_to_page(d->shared_info), d); - set_pfn_from_mfn(virt_to_phys(d->shared_info) >> PAGE_SHIFT, - INVALID_M2P_ENTRY); - d->arch.mm_perdomain_pt = alloc_xenheap_page(); - memset(d->arch.mm_perdomain_pt, 0, PAGE_SIZE); - set_pfn_from_mfn(virt_to_phys(d->arch.mm_perdomain_pt) >> PAGE_SHIFT, - INVALID_M2P_ENTRY); + pdpt_order = get_order_from_bytes(PDPT_L1_ENTRIES * sizeof(l1_pgentry_t)); + d->arch.mm_perdomain_pt = alloc_xenheap_pages(pdpt_order); + memset(d->arch.mm_perdomain_pt, 0, PAGE_SIZE << pdpt_order); v->arch.perdomain_ptes = d->arch.mm_perdomain_pt; /* @@ -293,9 +293,11 @@ void arch_do_createdomain(struct vcpu *v) d->arch.mm_perdomain_l2 = alloc_xenheap_page(); memset(d->arch.mm_perdomain_l2, 0, PAGE_SIZE); - d->arch.mm_perdomain_l2[l2_table_offset(PERDOMAIN_VIRT_START)] = - l2e_from_page(virt_to_page(d->arch.mm_perdomain_pt), - __PAGE_HYPERVISOR); + for ( i = 0; i < (1 << pdpt_order); i++ ) + d->arch.mm_perdomain_l2[l2_table_offset(PERDOMAIN_VIRT_START)+i] = + l2e_from_page(virt_to_page(d->arch.mm_perdomain_pt)+i, + __PAGE_HYPERVISOR); + d->arch.mm_perdomain_l3 = alloc_xenheap_page(); memset(d->arch.mm_perdomain_l3, 0, PAGE_SIZE); d->arch.mm_perdomain_l3[l3_table_offset(PERDOMAIN_VIRT_START)] = diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index c951de85b5..421d55de23 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -738,7 +738,7 @@ static int create_pae_xen_mappings(l3_pgentry_t *pl3e) memcpy(&pl2e[L2_PAGETABLE_FIRST_XEN_SLOT & (L2_PAGETABLE_ENTRIES-1)], &idle_pg_table_l2[L2_PAGETABLE_FIRST_XEN_SLOT], L2_PAGETABLE_XEN_SLOTS * sizeof(l2_pgentry_t)); - for ( i = 0; i < (PERDOMAIN_MBYTES >> (L2_PAGETABLE_SHIFT - 20)); i++ ) + for ( i = 0; i < PDPT_L2_ENTRIES; i++ ) pl2e[l2_table_offset(PERDOMAIN_VIRT_START) + i] = l2e_from_page( virt_to_page(page_get_owner(page)->arch.mm_perdomain_pt) + i, diff --git a/xen/arch/x86/shadow.c b/xen/arch/x86/shadow.c index e336878b9e..91a5624943 100644 --- a/xen/arch/x86/shadow.c +++ b/xen/arch/x86/shadow.c @@ -2710,7 +2710,7 @@ static unsigned long shadow_l3_table( &idle_pg_table_l2[L2_PAGETABLE_FIRST_XEN_SLOT], L2_PAGETABLE_XEN_SLOTS * sizeof(l2_pgentry_t)); - for ( i = 0; i < (PERDOMAIN_MBYTES >> (L2_PAGETABLE_SHIFT - 20)); i++ ) + for ( i = 0; i < PDPT_L2_ENTRIES; i++ ) spl2e[l2_table_offset(PERDOMAIN_VIRT_START) + i] = l2e_from_page( virt_to_page(page_get_owner(&frame_table[gmfn])->arch.mm_perdomain_pt) + i, diff --git a/xen/include/asm-x86/config.h b/xen/include/asm-x86/config.h index d24759aacb..960e381f1f 100644 --- a/xen/include/asm-x86/config.h +++ b/xen/include/asm-x86/config.h @@ -291,6 +291,9 @@ extern unsigned long xenheap_phys_end; /* user-configurable */ #define PDPT_VCPU_SHIFT 5 #define PDPT_VCPU_VA_SHIFT (PDPT_VCPU_SHIFT + PAGE_SHIFT) +#define PDPT_L1_ENTRIES (MAX_VIRT_CPUS << PDPT_VCPU_SHIFT) +#define PDPT_L2_ENTRIES \ + ((PDPT_L1_ENTRIES + (1 << PAGETABLE_ORDER) - 1) >> PAGETABLE_ORDER) #if defined(__x86_64__) #define ELFSIZE 64 -- 2.30.2